package com.study.other;

import com.google.common.collect.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;

import java.util.*;
import java.util.stream.Collectors;

public class MyUtils {

  public static void main(String[] args) throws Exception {
    test1();
    test2("TAng", "tang");
    test3();
    test4();
    test5();
    test6();
  }

  private static void test6() {
    //Multimap 一个key可以映射多个value的HashMap
    Multimap<String, Integer> map = ArrayListMultimap.create();
    map.put("key", 1);
    map.put("key", 2);
    Collection<Integer> values = map.get("key");
    System.out.println(map); // 输出 {"key":[1,2]}
    // 还能返回你以前使用的臃肿的Map省得你再创建 Map<String, List>
    Map<String, Collection<Integer>> collectionMap = map.asMap();

    //BiMap 一种连value也不能重复的HashMap
    BiMap<String, String> biMap = HashBiMap.create();
    //如果value重复,put方法会抛异常,除非用forcePut方法
    biMap.put("key", "value");
    System.out.println(biMap); // 输出 {"key":"value"}
    //既然value不能重复,何不实现个翻转key/value的方法，已经有了
    BiMap<String, String> inverse = biMap.inverse();
    System.out.println(inverse); // 输出 {"value":"key"}
    //Table 一种有两个key的HashMap
    // 一批用户,同时按年龄和性别分组
    Table<Integer, String, String> table = HashBasedTable.create();
    table.put(18, "男", "tang");
    table.put(18, "女", "Lily");
    System.out.println(table.get(18, "男")); // 输出 tang
    // 这其实是一个二维的Map,可以查看行数据
    Map<String, String> row = table.row(18);
    System.out.println(row); // 输出 {"男":"tang","女":"Lily"}
    // 查看列数据
    Map<Integer, String> column = table.column("男");
    System.out.println(column); // 输出 {18:"tang"}
    //Multiset 一种用来计数的Set
    Multiset<String> multiset = HashMultiset.create();
    multiset.add("apple");
    multiset.add("apple");
    multiset.add("orange");
    System.out.println(multiset.count("apple")); // 输出 2
    // 查看去重的元素
    Set<String> set = multiset.elementSet();
    System.out.println(set); // 输出 ["orange","apple"]
    // 还能查看没有去重的元素
    Iterator<String> iterator = multiset.iterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
    //还能手动设置某个元素出现的次数
    multiset.setCount("apple", 5);
  }

  private static void test5() {
    List<String> list = Lists.newArrayList();
    List<Integer> list1 = Lists.newArrayList(1, 2, 3);
    // 反转list
    List<Integer> reverse = Lists.reverse(list1);
    System.out.println(reverse); // 输出 [3, 2, 1]
    // list集合元素太多,可以分成若干个集合,每个集合10个元素
    List<List<Integer>> partition = Lists.partition(list1, 10);
    Map<String, String> map = Maps.newHashMap();
    Set<String> set = Sets.newHashSet();
  }

  private static void test4() throws Exception {
    //首字母转成大写
    String str = "tang";
    String capitalize = StringUtils.capitalize(str);
    System.out.println(capitalize); //Tang
    //重复拼接字符串
    String sb = StringUtils.repeat("tang", 2);
    System.out.println(sb); // 输出tangtang
    // 格式化日期 Date类型转String类型
    String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
    System.out.println(date); // 输出 2021-05-01 01:01:01
    // String类型转Date类型
    Date date1 = DateUtils.parseDate("2021-05-01 01:01:01", "yyyy-MM-dd HH:mm:ss");
    // 计算一个小时后的日期
    Date date2 = DateUtils.addHours(new Date(), 1);
    //包装临时对象(当一个方法需要返回两个及以上字段时,我们一般会封装成一个临时对象返回,现在有了Pair和Triple就不需要了)
    // 返回两个字段
    ImmutablePair<Integer, String> pair = ImmutablePair.of(1, "tang");
    System.out.println(pair.getLeft() + "," + pair.getRight()); // 输出 1,tang
    // 返回三个字段
    ImmutableTriple<Integer, String, Date> triple = ImmutableTriple.of(1, "tang", new Date());
    System.out.println(triple.getLeft() + "," + triple.getMiddle() + "," + triple
        .getRight()); // 输出 1,tang,Wed Apr 07 23:30:00 CST 2021
  }

  private static void test3() {
    //两个List集合取交集
    List<String> list1 = new ArrayList<>();
    list1.add("a");
    list1.add("b");
    list1.add("c");
    List<String> list2 = new ArrayList<>();
    list2.add("a");
    list2.add("b");
    list2.add("d");
    //jdk自带方法
    list1.retainAll(list2);
    System.out.println(list1); // 输出[a, b]
    // 两个集合取交集
    Collection<String> collection = CollectionUtils.retainAll(list1, list2);
    // 两个集合取并集
    collection = CollectionUtils.union(list1, list2);
    // 两个集合取差集
    collection = CollectionUtils.subtract(list1, list2);
  }

  /**
   * 比较两个字符串是否相等,忽略大小写
   */
  private static void test2(String strA, String strB) {
    if (strA.equalsIgnoreCase(strB)) {
      System.out.println("相等");
    }
    //比较两个对象是否相等(建议使用)
    System.out.println(Objects.equals(strA, strB));
  }

  /**
   * List集合拼接成以逗号分隔的字符串
   */
  private static void test1() {
    // 如何把list集合拼接成以逗号分隔的字符串 a,b,c
    List<String> list = Arrays.asList("a", "b", "c");
    // 第一种方法,可以用stream流
    String join = list.stream().collect(Collectors.joining(","));
    System.out.println(join); // 输出 a,b,c
    // 第二种方法,其实String也有join方法可以实现这个功能
    String join2 = String.join(",", list);
    System.out.println(join2); // 输出 a,b,c
    // 第三种方法,利用jdk1.8工具StringJoiner
    StringJoiner stringJoiner = new StringJoiner(",");
    list.stream().forEach(str -> {
      stringJoiner.add(str);
    });
    System.out.println(stringJoiner.toString());
  }
}
